import uvicorn
from api.upload_file_api import upload
from api.render_html_api import render
from fastapi.staticfiles import StaticFiles
from api.langchain_agent_api import agent
from fastapi.middleware.cors import CORSMiddleware
from middle_ware.logging_middle_ware import Logging_Middle_Ware
from langchain_community.chat_models import ChatOpenAI
from langchain_core.prompts import ChatPromptTemplate, SystemMessagePromptTemplate, HumanMessagePromptTemplate, MessagesPlaceholder
from langchain.memory import ConversationBufferMemory
from langchain.agents import create_structured_chat_agent, AgentExecutor
from langchain import hub
from api.langchain_chat_api import *
from api.langchain_load_file_api import *
from api.xbase_api.xbase_department_query import api_department_query
from api.xbase_api.xbase_department_create import api_department_create
from api.xbase_api.xbase_employee_create import api_employee_create
from api.xbase_api.xbase_employee_query import api_employee_query
from api.xbase_api.xbase_create_bug import api_create_bug
from tortoise.contrib.fastapi import register_tortoise
from orm.settings import TORTOISE_ORM
from utils.load_config_yaml import load_yaml
# from api.xbase_api import api_bug
from tortoise.contrib.fastapi import register_tortoise
from orm.settings import TORTOISE_ORM
from utils.load_config_yaml import load_yaml
from api.xbase_api.xbase_department_query import api_department_query
from api.xbase_api.xbase_department_create import api_department_create
from api.xbase_api.xbase_employee_create import api_employee_create
from api.xbase_api.xbase_employee_query import api_employee_query
# 接口平台导入相关
from api.xbase_api.xbase_user_login_api import api_login
from api.xbase_api.xbase_user_logout_api import api_logout
from api.xbase_api.xbase_user_getInfo_api import api_userInfo
from api.xbase_api.xbase_user_register_api import api_register
from api.xbase_api.xbase_model_api import api_model
static_path = os.path.join(os.path.dirname(__file__), "static")

app = FastAPI()

app.add_middleware(Logging_Middle_Ware)

app.add_middleware(CORSMiddleware,
                   allow_origins=["*"],
                   allow_credentials=True,
                   allow_methods=["GET", "POST", "PUT", "DELETE"],
                   allow_headers=["Content-Type"]
                   # allowed_hosts=["*"]  #可以限制哪些主机可以访问应用
                   )
# 以下是关于大模型相关的接口
app.include_router(chat_app, prefix='/fjh_chat_llm', tags=['大模型聊天'])
app.include_router(llm_load_file, prefix='/fjh_load_llm', tags=['大模型文件加载'])
app.include_router(upload, prefix='/upload', tags=['上传文件'])
app.include_router(render, prefix='/render', tags=['渲染html'])
app.include_router(agent, prefix="/model_openapi", tags=['xbase_model'])
# 以下是关于xbase相关的接口
app.include_router(api_department_create,
                   prefix='/xbase_department',
                   tags=['xbase的部门'])
app.include_router(api_department_query,
                   prefix='/xbase_department',
                   tags=['查询xbase的部门'])
app.include_router(api_employee_create,
                   prefix='/xbase_employee',
                   tags=['xbase的员工'])
app.include_router(api_employee_query,
                   prefix='/xbase_employee',
                   tags=['查询xbase的员工'])
app.include_router(api_create_bug,
                   prefix='/xbase_bug',
                   tags=['新建缺陷'])

# 接口平台接口
app.include_router(api_login,prefix='/Api_Platform',tags=['接口平台'])
app.include_router(api_logout,prefix='/Api_Platform',tags=['接口平台'])
app.include_router(api_register,prefix='/Api_Platform',tags=['接口平台'])
app.include_router(api_model,prefix='/Api_Platform',tags=['模型接口列表'])
app.include_router(api_userInfo,
                   prefix='/Api_Platform',
                   tags=['获取用户信息'])

# fastapi一旦运行，这里就执行了
register_tortoise(app=app, config=TORTOISE_ORM)

app.mount('/static', StaticFiles(directory=static_path), name='static')

#设置one-api
ONEAPI_API_BASE = load_yaml()['one_api'].get('ONEAPI_API_BASE', '')
ONEAPI_CHAT_API_KEY = load_yaml()['one_api'].get('ONEAPI_CHAT_API_KEY', '')
ONEAPI_CHAT_MODEL = load_yaml()['one_api'].get('ONEAPI_CHAT_MODEL', '')
ONEAPI_EMBEDDING_API_KEY = load_yaml()['one_api'].get(
    'ONEAPI_EMBEDDING_API_KEY', '')
ONEAPI_EMBEDDING_MODEL = load_yaml()['one_api'].get('ONEAPI_EMBEDDING_MODEL',
                                                    '')


class Master:

    def __init__(self):
        #初始化ChatOpenAI
        self.llm = ChatOpenAI(
            base_url=ONEAPI_API_BASE,
            api_key=ONEAPI_CHAT_API_KEY,
            model=ONEAPI_CHAT_MODEL,  # 本次使用的模型
            temperature=0,  # 发散的程度，一般为0
            timeout=None,  # 服务请求超时
            max_retries=2,  # 失败重试最大次数
        )
        #设置记忆存储键名
        self.memory_key = "chat_history_test"
        #设置系统提示词模板
        self.messages = [
            SystemMessagePromptTemplate.from_template(
                "你是一位得力的ai助手，可以协助用户处理问题，同时对于历史提过的问题以及回答，同样可以快读的输出"),
            MessagesPlaceholder(variable_name=self.memory_key),
            HumanMessagePromptTemplate.from_template('{fjh_input}')
        ]
        self.prompt = ChatPromptTemplate.from_messages(messages=self.messages)
        self.memory = ConversationBufferMemory(memory_key=self.memory_key,
                                               return_messages=True,
                                               llm=self.llm)
        #定义agent
        tools = []
        hub_prompt = hub.pull("hwchase17/structured-chat-agent")
        agent = create_structured_chat_agent(llm=self.llm,
                                             prompt=self.prompt,
                                             tools=tools)
        self.agent_executor = AgentExecutor.from_agent_and_tools(agent=agent,
                                                                 tools=tools,
                                                                 verbose=True)

        #定义运行方法
        def run(self, query):
            response = self.agent_executor.invoke({"fjh_input": query})
            #返回执行器的结果
            return response


@app.get('/main')
async def get():
    return "welcome to fastapi main"


@app.post('/chat')
def chat(query: str):
    master = Master()  #初始化对象
    return master.run(query)


if __name__ == '__main__':
    uvicorn.run(app='main:app', host='0.0.0.0', port=8111, reload=True)
